package com.glodon.paas.account.dao.mongo;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;

import com.glodon.paas.account.dao.DBDao;
import com.glodon.paas.util.GenericsUtil;
import com.google.code.morphia.DatastoreImpl;
import com.google.code.morphia.query.Query;
import com.google.code.morphia.query.UpdateOperations;

@SuppressWarnings({ "unchecked"})
public class MongoDBDao<T, K> implements DBDao<T, K>{

	protected Class<T> entityClazz;
	
	@Autowired
	protected DatastoreImpl mongoDataStore;

	protected MongoDBDao() {
		entityClazz = GenericsUtil.getClazz(this.getClass());
	}
	
	public void ensureIndexes() {
		mongoDataStore.ensureIndexes(entityClazz);
	}
	
	@PostConstruct
	public void init() {
		mongoDataStore.getMapper().addMappedClass(entityClazz);
		this.ensureIndexes();
	}

	public void setEntityClazz(Class<T> entityClazz) {
		this.entityClazz = entityClazz;
	}
	
	public T get(K id) {
		return mongoDataStore.get(entityClazz, id);
	}
	
	
	public K insert(T entity) {
		return (K) mongoDataStore.insert(entity).getId();
	}

	public int delete(K id) {
		return mongoDataStore.delete(entityClazz, id).getN();
	}
	
	public Query<T> createQuery() {
		return mongoDataStore.createQuery(entityClazz);
	}
	
	public UpdateOperations<T> createUpdateOperations() {
		return mongoDataStore.createUpdateOperations(entityClazz);
	}
	
	public int updateFirst(Query<T> q, UpdateOperations<T> ops) {
		return mongoDataStore.updateFirst(q, ops).getUpdatedCount();
	}
	
	public int deleteByQuery(Query<T> q) {
		return mongoDataStore.delete(q).getN();
	}
	
	public long count(Query<T> q) {
		return mongoDataStore.getCount(q);
	}
	
	public int update(Query<T> q, T entity){
		return mongoDataStore.updateFirst(q, entity, false).getUpdatedCount();
	}
}
